// 通过 zlib 进行文件传输 - todo
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <iostream>
#include <signal.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <string>
using namespace std;

static const char *ip = "192.168.232.128";
static const int port = 12345;
static const char* FILE_PATH = "payload.txt";


bufferevent_filter_result client_filter_out(
    struct evbuffer *src, struct evbuffer *dst, ev_ssize_t dst_limit,
    enum bufferevent_flush_mode mode, void *ctx) {
    
    cout << "filter out" << endl;
    
    return BEV_OK;
}

void client_read_cb(bufferevent *bev, void *args) {
    char data[1024] = {0};
    int len = bufferevent_read(bev, data, sizeof(data) - 1);
    cout << "recv" << data << endl;

}

void client_write_cb(bufferevent *bev, void *args) {
    
}

void client_event_cb(bufferevent *bev, short what, void *ctx) {
    cout << "client event cb" << endl;
    // if (what & BEV_EVENT_CONNECTED) {
    //     cout << "connect event" << endl;
    // }
    if (what & BEV_EVENT_CONNECTED) {
        cout << "client: connect event" << endl;
        bufferevent_write(bev, FILE_PATH, sizeof(FILE_PATH));
        bufferevent *bev_filter = bufferevent_filter_new(bev, 0, client_filter_out, BEV_OPT_CLOSE_ON_FREE, 0, 0);
        bufferevent_setcb(bev_filter, client_read_cb, client_write_cb, client_event_cb, ctx);
        bufferevent_enable(bev_filter, EV_READ | EV_WRITE);
    }
}

int main() {
    cout << "begin client" << endl;
    event_base *base = event_base_new();
    if (base) {
        cout << "create new event base" << endl;
    }
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    evutil_inet_pton(AF_INET, ip, &sin.sin_addr);

    // 设置 bev
    bufferevent * bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_enable(bev, EV_READ|EV_WRITE);
    bufferevent_setcb(bev, 0, 0, client_event_cb, 0);

    // 连接服务端
    bufferevent_socket_connect(bev, (sockaddr*)&sin, sizeof(sin));
    
    // 进入事件主循环
    assert(base);
    event_base_dispatch(base);
    event_base_free(base);

}